/*###########################################################
# © 2013-2016 Daniel 'grindhold' Brendle
#
# This file is part of Nostril.
#
# Nostril is free software: you can redistribute it and/or 
# modify it under the terms of the GNU Affero General Public License 
# as published by the Free Software Foundation, either 
# version 3 of the License, or (at your option) any later 
# version.
#
# Nostril is distributed in the hope that it will be 
# useful, but WITHOUT ANY WARRANTY; without even the implied 
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public 
# License along with Nostril. 
# If not, see http://www.gnu.org/licenses/.
###########################################################*/

using Soup;

namespace nostril {
    public class ProxyServer : Soup.Server {
        private data.MessageStore ms = null;
        private static Soup.SessionAsync async_session = new Soup.SessionAsync();

        public ProxyServer (data.MessageStore ms) {
            Object (port: 8088);
            assert (this != null);

            this.ms = ms;
            this.add_handler (null, default_handler);
        }

        private static void default_handler (Soup.Server server, Soup.Message msg, string path, GLib.HashTable? query, Soup.ClientContext client) {
            unowned ProxyServer self = server as ProxyServer;

            Timeout.add_seconds (0, () => {
                uint8[] reqdata = msg.request_body.data;
                int messagelog_id = self.ms.store_message(msg,reqdata);

                Soup.Message target_msg = new Soup.Message.from_uri (msg.method, msg.uri);
                msg.request_headers.foreach((name, val) => {
                    target_msg.request_headers.append(name,val);
                });
                ProxyServer.async_session.queue_message (target_msg, (sess, target_msg_inc)=> {
                    string content_type = target_msg_inc.response_headers.get_content_type(null);

                    msg.set_response (content_type, Soup.MemoryUse.COPY, target_msg_inc.response_body.data);
                    msg.set_status (target_msg_inc.status_code);

                    target_msg_inc.response_headers.foreach((name, val) => {
                        if (name.down() != "date"){
                            msg.response_headers.append(name,val);
                        }
                    });
                    if (content_type == "(null)") {
                        msg.response_headers.remove("Content-type");
                    }
                    uint8[] resdata = target_msg_inc.response_body.data;
                    self.ms.complete_message(messagelog_id, msg, resdata);

                    self.unpause_message (msg);
                });
                return false;
            }, Priority.DEFAULT);

            self.pause_message (msg);
        }
    }
}
